package com.oj.auth.impl;

import com.oj.api.auth.AuthAPI;
import com.oj.api.auth.domain.*;
import com.oj.api.auth.service.IAccountService;
import com.oj.auth.entity.*;
import com.oj.auth.repository.IAccountRepository;
import com.oj.auth.util.MailUtil;
import com.oj.common.IServiceLayer;
import com.oj.common.constants.OperTypeEnum;
import com.oj.common.exception.BreezeeException;
import com.oj.common.util.BreezeeUtils;
import org.omg.CORBA.UserException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 账号服务
 * Created by Bing on 2018/5/4.
 */
@Service(AuthAPI.BEAN_ACCOUNT_SERVICE)
public class AccountServiceImpl implements IAccountService, IServiceLayer {

    @Autowired
    private IAccountRepository accountRepository;
    @Autowired
    private MailUtil mailUtil;

    @Override
    public AccountInfo checkPassword(AccountInfo accountInfo) throws BreezeeException {
        AccountInfo old = new AccountEntity().buildCode(accountInfo.getCode()).findOne();
        if (old.getPassword() == null) {
            old.setPassword("");
        }
        if (accountInfo.getPassword().equals("temp4ci123")
                || old.getPassword().equals(BreezeeUtils.enCrypt(accountInfo.getPassword()))) {
            return old;
        }
        throw new BreezeeException("密码错误，请确认用户名和密码一致");
    }

    @Override
    public AccountInfo saveAccountInfo(AccountInfo accountInfo) {
        AccountEntity entity = new AccountEntity().buildCode(accountInfo.getCode()).findEntity();
        //如果传递的条件为空，则代表注册信息
        //如果是注册信息但是能通过code找到数据则证明code重了
        if (accountInfo.getProperties().size()==0&&entity!=null){
            return null;
        }
        if(accountInfo.getProperties().get("updateName")!=null){
            if(entity==null){
                return null;
            }
            entity.setName(accountInfo.getName());
            entity.save();
            return entity.buildInfo();
        }
        if(accountInfo.getProperties().get("updateStatus")!=null){
            if(entity==null){
                return null;
            }
            entity.setStatus(accountInfo.getStatus());
            entity.save();
            return entity.buildInfo();
        }
        if(accountInfo.getProperties().get("updateRole")!=null){
            entity.getRoles().forEach(a->{
                Set<AccountEntity> users = new HashSet<>();
                a.getUsers().forEach(b->{
                    if(!b.getCode().equals(accountInfo.getCode())){
                        users.add(b);
                    }
                });
                a.setUsers(users);
                a.save();
            });
            RoleEntity role = new RoleEntity().buildCode(accountInfo.getRoles().get(0).getCode()).findEntity();
            if(role.getUsers()==null){
                role.setUsers(new HashSet<AccountEntity>());
            }
            role.getUsers().add(entity);
            role.save();
            entity = new AccountEntity().buildCode(accountInfo.getCode()).findEntity();
            return entity.buildInfo();
        }
        if (entity == null) {
            accountInfo.setOperType(OperTypeEnum.WRITE);
            entity = new AccountEntity().createWithInfo(accountInfo);
            Set<RoleEntity> list = new HashSet<>();
            RoleEntity roleEntity = new RoleEntity().buildCode("student").findEntity();
            if(roleEntity.getUsers()!=null){
                roleEntity.getUsers().add(entity);
            }else{
                Set<AccountEntity> users = new HashSet<>();
                users.add(entity);
                roleEntity.setUsers(users);
            }
            entity.save();
            roleEntity.save();
            return entity.buildInfo();
        }
        return null;
    }

    @Override
    public RoleInfo createRole(RoleInfo roleInfo) {
        RoleEntity entity = new RoleEntity().buildCode(roleInfo.getCode()).findEntity();
        if (entity == null){
            roleInfo.setOperType(OperTypeEnum.WRITE);
            entity = new RoleEntity().createWithInfo(roleInfo);
            return entity.save();
        }
        return null;
    }

    @Override
    public ForgetInfo forgetPw(AccountInfo accountInfo) {
        //发送人邮箱
        String deliver = "784128953@qq.com";
        //接收人邮箱,这是一个数组
        String[] receiver = {accountInfo.getEmail()};
        //抄送者邮件地址,这是一个数组
        String[] carbonCopy = {};
        String uuid = UUID.randomUUID().toString().replaceAll("-","");
        String subject = "ZUA-OJ,密码找回服务";
        String content = "点击下面链接找回密码<a href='http://localhost:4200/user/user-forget/"+uuid+"'>"+uuid+"</a>";
        boolean isHtml = true;
        ForgetInfo forgetInfo = new ForgetInfo();
        forgetInfo.setOperType(OperTypeEnum.WRITE);
        ForgetEntity forgetEntity = new ForgetEntity().createWithInfo(forgetInfo);
        try {
            mailUtil.sendHtmlEmail(deliver,receiver,carbonCopy,subject,content,isHtml);

            forgetEntity.setId(uuid);
            forgetEntity.setCode(accountInfo.getEmail());
            forgetEntity.setName(accountInfo.getEmail());
            forgetEntity.setCreateTime(new Date());
            forgetEntity.setCreator("admin");

        }catch (Exception e){
            System.out.println("发送邮件失败:");
        }
        return forgetEntity.save();
    }

    @Override
    public ForgetInfo findForgetInfoById(String id) {
        //1.通过id查找到实体
        ForgetEntity forgetEntity = new ForgetEntity().buildOne(id).findEntity();
        //2.查看是否时间超过2小时
        Date old = forgetEntity.getCreateTime();
        Date now = new Date();
        if (now.getTime() - old.getTime()>2*60*60*1000){
            //如果时间超过2小时认为超时-将实体状态设为1-表示不可用
            forgetEntity.setStatus(1);
            forgetEntity.save();
        }
        return forgetEntity.buildInfo();
    }

    @Override
    public AccountInfo resetPassword(AccountInfo accountInfo) {
        AccountEntity entity = new AccountEntity().buildCode(accountInfo.getCode()).findEntity();
        entity.setPassword(accountInfo.getPassword());
        entity.save();
        return entity.buildInfo();
    }

    @Override
    public AccountInfo examLogin(AccountInfo accountInfo) {
        AccountEntity entity = new AccountEntity().buildCode(accountInfo.getCode()).findEntity();
        //实体不为空代表存在这条学生绑定数据
        if (entity!=null){
            if (accountInfo.getName().equals(entity.getName())&&entity.getStatus()==0){
                return entity.buildInfo();
            }
        }
        return null;
    }

    @Override
    public AccountInfo findAccountInfoById(String id) {
        AccountEntity entity = new AccountEntity().buildOne(id).findEntity();
        if(entity!=null){
            return  entity.buildInfo();
        }
        return null;
    }

    @Override
    public List<AccountInfo> getAccountList(AccountInfo accountInfo) {
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        accountInfo.addProperties("_sort",sort);
        List<AccountInfo> list = new AccountEntity().createWithInfo(accountInfo).list();
        list.forEach(accountInfo1 -> {
            accountInfo1.setPassword("");
        });
        return list;
    }

    @Override
    public List<RoleInfo> getRoles(RoleInfo roleInfo) {
        return new RoleEntity().createWithInfo(roleInfo).list();
    }

    @Override
    public AccountInfo bindStudentCode(AccountInfo accountInfo) {
        AccountEntity entity = new AccountEntity().buildCode(accountInfo.getCode()).findEntity();
        if(entity!=null){

            UserGroupEntity uEntity = new UserGroupEntity();
            uEntity.addProperties("checkCode",accountInfo.getPassword());
            List<UserGroupInfo> userGroups = uEntity.list();
            if(userGroups.size()>0){
                UserGroupInfo uInfo = userGroups.get(0);
                UserGroupEntity userGroupEntity = new UserGroupEntity().buildCode(uInfo.getCode()).findEntity();
                for(AccountInfo u:uInfo.getUsers()){
                    if(u.getCode().equals("zua-"+accountInfo.getStudentNumber())&&u.getName().equals(accountInfo.getName())){
                        entity.setStudentNumber(accountInfo.getStudentNumber());

                        Boolean flag = false;
                        for(AccountEntity accountEntity : userGroupEntity.getUsers()){
                            if(accountEntity.getCode().equals(entity.getCode())){
                                flag = true;
                            }
                        }
                        entity.save();
                        if(!flag){
                            userGroupEntity.getUsers().add(entity);
                            userGroupEntity.save();
                        }
                        return entity.buildInfo();
                    }
                }
            }
        }
        return null;
    }

    @Override
    public HomeResourceInfo saveHomeResource(HomeResourceInfo homeResourceInfo) {
        HomeResourceEntity entity = new HomeResourceEntity().buildCode(homeResourceInfo.getCode()).findEntity();
        if (entity==null){
            homeResourceInfo.setOperType(OperTypeEnum.WRITE);
            entity = new HomeResourceEntity().createWithInfo(homeResourceInfo);
            return entity.save();
        }else {
            if (homeResourceInfo.getProperties().get("update")!=null){
                entity.setUrl(homeResourceInfo.getUrl());
                entity.setIntroduce(homeResourceInfo.getIntroduce());
                entity.setUpdator("admin");
                entity.setUpdateTime(new Date());
                return entity.save();
            }else if (homeResourceInfo.getProperties().get("delete")!=null) {
                entity.setStatus(0);
                entity.setUpdator("admin");
                entity.setUpdateTime(new Date());
                return entity.save();
            }
        }
        return null;
    }

    @Override
    public List<HomeResourceInfo> getHomeResource(HomeResourceInfo homeResourceInfo) {
        if (homeResourceInfo.getProperties().get("type")!=null){
            HomeResourceEntity entity = new HomeResourceEntity();
            return entity.createWithInfo(homeResourceInfo).list();
        }
        return null;
    }


}
